#pragma once
#include "md5_tokens.h"

#include <string>
#include <deque>
#include <vector>
#include <fstream>

namespace krryn{
namespace data{
	class md5_lexer_exception{};
	class md5_lexer_eof : public md5_lexer_exception{};

	class md5_lexer{
	public:
		typedef md5_token store_t;
		typedef std::deque<md5_token> token_stack;

		md5_lexer(const std::string &a_Filename);
		md5_token scan();
		unsigned int line();
	private:
		typedef std::vector<std::string> parts_t;
		
		std::vector<std::string> m_Keywords;
		token_stack m_Tokens;
		std::ifstream m_Stream;
		unsigned int m_LineNumber;

		std::string read_lexeme();

		md5_token tokenize(const std::string &a_String);
		md5_token make(md5_tags a_Tag, const std::string &a_Value);
		md5_token make_keyword(const std::string &a_Value);

		// we may want to refactor this into a helper class, these functions 
		// feel too generic for this class
		bool is_real(const std::string &a_String);
		bool is_integer(const std::string &a_String);
		bool is_keyword(const std::string &a_String);
		bool has_sign(const std::string &a_String);
	};
}
}